﻿using MyDLL.Properties;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace MyDLL.HtmlCharConverter
{
    /// <summary>
    /// HTML特殊字符转换器
    /// </summary>
    public class Converter
    {
        private static Converter _instance = null;

        private Dictionary<char, Entry> _entries = null;

        private Regex _regexEntityName = new Regex("&[A-Za-z]+;");
        private Regex _regexEntityNumber = new Regex("&#[0-9]+;");

        /// <summary>
        /// HTML特殊字符集合
        /// </summary>
        public Dictionary<char, Entry> Entries 
        {
            get 
            {
                if (_entries == null)
                {
                    SetEntries();
                }
                return _entries;
            }
        }

        /// <summary>
        /// 获取Converter实例
        /// </summary>
        public static Converter Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new Converter();
                }
                return _instance;
            }
        }

        private void SetEntries()
        {
            var str = Encoding.UTF8.GetString(Resources.HTML特殊字符表Json);
            _entries = JsonUtility.DeserializeObject_FromString<Dictionary<char, Entry>>(str);
        }

        #region Character2EntityName
        /// <summary>
        /// 将Character转化为EntityName
        /// </summary>
        /// <param name="c">待查询的Character</param>
        /// <returns></returns>
        public string Character2EntityName(char c)
        {
            string res;
            try
            {
                res = _entries[c].HtmlEntityName;
            }
            catch (Exception)
            {

                res = c.ToString();
            }
            return res;
        }

        /// <summary>
        /// 将Character字符串转化为EntityName字符串
        /// </summary>
        /// <param name="charStr"></param>
        /// <returns></returns>
        public string CharacterStr2EntityNameStr(string charStr)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var c in charStr)
            {
                sb.Append(Character2EntityName(c));
            }
            return sb.ToString();
        }
        #endregion

        #region EntityName2Character
        /// <summary>
        /// 将EntityName转化为Character。
        /// </summary>
        /// <param name="ename">待查询的EntityName</param>
        /// <returns></returns>
        public string EntityName2Character(string ename)
        {
            char res = (from x in _entries.Values
                        where x.HtmlEntityName == ename
                        select x.Character).FirstOrDefault();
            return res == '\0' ? ename : res.ToString(); // char的默认值为'\0'。
        }

        /// <summary>
        /// 将EntityName字符串转化为Character字符串。
        /// </summary>
        /// <param name="enameStr">待查询的EntityName</param>
        /// <returns></returns>
        public string EntityNameStr2CharacterStr(string enameStr)
        {
            string res = enameStr;
            while (_regexEntityName.IsMatch(res))
            {
                res = _regexEntityName.Replace(res, m => EntityName2Character(m.Value)); 
            }

            return res;
        }
        #endregion

        #region Character2EntityNumber
        /// <summary>
        /// 将Character转化为EntityNumber
        /// </summary>
        /// <param name="c">待查询的Character</param>
        /// <returns></returns>
        public string Character2EntityNumber(char c)
        {
            string res;
            try
            {
                res = _entries[c].HtmlEntityNumber;
            }
            catch (Exception)
            {

                res = c.ToString();
            }
            return res;
        }

        /// <summary>
        /// 将Character字符串转化为EntityNumber字符串
        /// </summary>
        /// <param name="charStr"></param>
        /// <returns></returns>
        public string CharacterStr2EntityNumberStr(string charStr)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var c in charStr)
            {
                sb.Append(Character2EntityNumber(c));
            }
            return sb.ToString();
        }
        #endregion

        #region EntityNumber2Character
        /// <summary>
        /// 将EntityNumber转化为Character。
        /// </summary>
        /// <param name="enumber">待查询的EntityNumber</param>
        /// <returns></returns>
        public string EntityNumber2Character(string enumber)
        {
            char res = (from x in _entries.Values
                        where x.HtmlEntityNumber == enumber
                        select x.Character).FirstOrDefault();
            return res == '\0' ? enumber : res.ToString(); // char的默认值为'\0'。
        }

        /// <summary>
        /// 将EntityNumber字符串转化为Character字符串。
        /// </summary>
        /// <param name="enumberStr">待查询的EntityName</param>
        /// <returns></returns>
        public string EntityNumberStr2CharacterStr(string enumberStr)
        {
            string res = enumberStr;
            while (_regexEntityNumber.IsMatch(res))
            {
                res = _regexEntityNumber.Replace(res, m => EntityNumber2Character(m.Value));
            }
            return res;
        }
        #endregion

        /// <summary>
        /// Prevents a default instance of the 
        /// <see cref="Converter"/> class from being created.
        /// </summary>
        private Converter()
        {
            SetEntries();
        }

    }
}
